<template>
  <el-card class="box-card mb-1" id="search">
    <el-form
      :model="forms"
      :rules="rules"
      ref="ruleForm"
      :inline="true"
      size="mini"
    >
      <slot
        v-for="item in config.form"
        :key="item.key"
        :name="item.key"
        :row="item"
      >
        <el-form-item :label="item.label" :prop="item.key" v-if="!item.hide">
          <template v-if="item.type == 'select'">
            <el-select
              v-if="item.remote === true"
              v-model="forms[item.key]"
              :placeholder="item.placeholder || '请选择'"
              :loading="selectOptions[item.key].remoteLoading"
              :remote-method="remoteMethod(item.key)"
              filterable
              remote
            >
              <el-option
                v-for="opt in selectOptions[item.key].list"
                :key="opt.value"
                :label="opt.label"
                :value="opt.value"
              >
              </el-option>
            </el-select>
            <el-select
              v-else
              v-model="forms[item.key]"
              :placeholder="item.placeholder || '请选择'"
            >
              <el-option
                v-for="opt in item.options"
                :key="opt.value"
                :label="opt.label"
                :value="opt.value"
              >
              </el-option>
            </el-select>
          </template>
          <template v-else-if="item.commentsName === 'datePicker'">
            <el-date-picker
              v-model="forms[item.key]"
              :type="item.type"
              :placeholder="item.placeholder || '请选择'"
              :format="item.format || 'YYYY-MM-DD'"
              :value-format="item.format || 'YYYY-MM-DD'"
              :start-placeholder="item.startPlaceholder || '请选择开始日期'"
              :end-placeholder="item.endPlaceholder || '请选择结束日期'"
              :disabledDate="item.disabledDate || ''"
              :range-separator="item.disabledDate || '至'"
              :shortcuts="item.shortcuts || []"
            >
            </el-date-picker>
          </template>
          <template v-else-if="item.commentsName === 'timeSelect'">
            <el-time-select
              v-model="forms[item.key]"
              :start="item.start"
              :step="item.step"
              :end="item.end"
              :placeholder="item.placeholder || '请选择'"
            >
            </el-time-select>
          </template>
          <template v-else>
            <el-input
              @input="inputLimiting(item.key, item.handlerLimiting)"
              v-model.trim="forms[item.key]"
              :maxlength="item.maxlength"
              :type="item.type"
              :placeholder="item.placeholder || '请选择'"
            ></el-input>
          </template>
        </el-form-item>
      </slot>
      <el-form-item>
        <el-button
          icon="el-icon-search"
          type="primary"
          @click="handlerSearch()"
          :loading="loading"
          >{{ loading ? "搜索中" : "搜索" }}</el-button
        >
        <el-button
          :disabled="loading"
          icon="el-icon-refresh"
          @click="queryResetForm()"
          >重置</el-button
        >
      </el-form-item>
    </el-form>
  </el-card>
</template>

<script>
import { reactive, toRefs, getCurrentInstance, onMounted, watch } from 'vue';
export default {
	props : {
		modelValue : {
			type : Object,
			required : true
		},
		config : {
			type : Object,
			required : true
		}
	},
	setup (ctx, context) {
		let ruleForm = null;
		let data = reactive({
			loading : false,
			forms : {},
			rules : {},
			selectOptions : {}
		});

		onMounted(() => {
			// TODO: ref重名问题???待发现
			ruleForm = getCurrentInstance().proxy.$refs['ruleForm'];
		});

		ctx.config.form.forEach((item) => {
			// 默认值
			data.forms[item.key] = item.defaultValue;
			// 组装验证器
			data.rules[item.key] = item.rules;
			// 远程搜索列表映射
			if (item.remote) {
				data.selectOptions[item.key] = {
					remoteLoading : false,
					list : []
				};
			}
		});
		context.emit('update:modelValue', data.forms);
		// 搜索
		let handlerSearch = () => {
			ruleForm.validate(async (valid) => {
				if (valid) {
					data.loading = true;
					let params = {};
					Object.keys(data.forms).forEach((key) => {
						if (
							data.forms[key] !== '' &&
              data.forms[key] !== 'null' &&
              data.forms[key] !== 'undefined' &&
              data.forms[key] !== null &&
              data.forms[key] !== undefined
						) {
							params[key] = data.forms[key];
						}
					});
					await ctx.config.handlerSearch(params);
					data.loading = false;
				}
			});
		};

		// 重置
		let queryResetForm = async () => {
			Object.keys(data.forms).forEach((key) => {
				data.forms[key] = '';
			});
			ruleForm.resetFields();
			await ctx.config.handlerSearch();
			data.loading = false;
		};

		// 远程搜索
		let remoteMethod = (key) => {
			let res = ctx.config.form.find((item) => item.key === key);
			return async (query) => {
				if (query !== '') {
					data.selectOptions[key].remoteLoading = true;
					data.selectOptions[key].list = await res.getOptions();
					data.selectOptions[key].remoteLoading = false;
				} else {
					data.selectOptions[key].list = [];
					data.selectOptions[key].remoteLoading = false;
				}
			};
		};

		// 输入限制
		let inputLimiting = (key, callback) => {
			if (callback) {
				data.forms[key] = callback(data.forms[key]);
			}
		};

		watch(data.forms, () => {
			context.emit('update:modelValue', data.forms);
		});

		return {
			inputLimiting,
			handlerSearch,
			queryResetForm,
			remoteMethod,
			...toRefs(data)
		};
	}
};
</script>

<style lang="scss" scoped></style>
